#pragma once

#include "ukui-wayland-client-core.h"

namespace ukuiwaylandclient
{

class wl_event_queue_t;
class wl_callback_t;

class wl_display_t
{
public:
    wl_display_t(int fd);
    wl_display_t(const char *name = {});
    wl_display_t(struct ::wl_display *object);

    ~wl_display_t();

    static const struct ::wl_interface *interface();

    enum error {
        error_invalid_object = 0, // server couldn't find object
        error_invalid_method = 1, // method doesn't exist on the specified interface or malformed request
        error_no_memory = 2, // server is out of memory
        error_implementation = 3, // implementation error in compositor
    };

    // Wayalnd display core functions
    int get_fd() const;
    int dispatch() const;
    int dispatch_queue(wl_event_queue_t *queue) const;
    int dispatch_queue_pending(wl_event_queue_t *queue) const;
    int dispatch_pending() const;
    error get_error() const;
    int flush() const;
    int roundtrip_queue(wl_event_queue_t *queue) const;
    int roundtrip() const;
    wl_event_queue_t *create_queue() const;
    wl_event_queue_t *create_queue_with_name(const char *name) const;
    int prepare_read_queue(struct wl_event_queue *queue);
    int prepare_read();
    void cancel_read();
    int read_events();
    void set_log_handler(wl_log_func_t handler);
    void set_max_buffer_size(size_t max_buffer_size);

    // Wayland protocol functions
    wl_callback_t *sync();
    wl_registry_t *get_registry();

private:
    struct ::wl_display *m_wl_display;
};

class wl_event_queue_t
{
public:
    wl_event_queue_t(struct ::wl_event_queue *object);

    ~wl_event_queue_t();

    const char *get_name() const;

private:
    struct ::wl_event_queue *m_wl_event_queue;

    friend class wl_display_t;
};

} // namespace ukui::wayland::client